<?php

declare(strict_types=1);
/**
 * Author: Zane
 * Email: 873934580@qq.com
 * Date: 2023/6/27.
 */

namespace App\Http\Controllers\System;

use App\Exceptions\CommonExceptionConstants;
use App\Exceptions\ServiceException;
use App\Http\Controllers\Controller;
use App\Models\Attachment;
use App\Utils\ResultsVo;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Config;
use Illuminate\Support\Facades\Storage;

class UploadController extends Controller
{
    private $filename;
    private $group;

    public function upload(Request $request): \Illuminate\Http\JsonResponse
    {
        if (!$request->hasFile($this->getFilename())) {
            throw new ServiceException(CommonExceptionConstants::FILE_INVALID);
        }
        $file = $request->file($this->getFilename());
        if (!$file->isValid()) {
            throw new ServiceException(CommonExceptionConstants::FILE_INVALID);
        }

        $data = [
            'md5' => hash_file('md5', $file->getPathname()),
            'title' => $file->getClientOriginalName(),
            'type' => $file->getMimeType(),
            'suffix' => $file->clientExtension(),
            'size' => $file->getSize(),
            'driver' => $this->getDriver(),
            'groups' => $this->getGroup(),
        ];
        $result = Attachment::byMd5($data['md5']);
        if ($result) {
            return ResultsVo::success($result);
        }
        // TODO: 增加云存储方案
        $path = Storage::putFile($this->getPath(), $file);
        if (false === $path) {
            throw new ServiceException(CommonExceptionConstants::FILE_STORAGE_FAIL);
        }
        $data['path'] = $path;
        $data['url'] = Storage::url($path);
        $dao = new Attachment();
        $dao->fill($data)->save();

        return ResultsVo::success($dao);
    }

    protected function getPath(): string
    {
        $path = $this->getGroup();
        $public = Config::get('filesystems.disks.public.visibility');

        return $public.'/'.$path.'/'.date('Ymd', time());
    }

    /**
     * @return mixed
     */
    private function getDriver(): string
    {
        return Config::get('filesystems.default');
    }

    private function getFilename()
    {
        if (!$this->filename) {
            $this->filename = request()->get('filename', 'file');
        }

        return $this->filename;
    }

    /**
     * 上传分组.
     *
     * @return mixed
     */
    private function getGroup()
    {
        if (!$this->group) {
            $this->group = request()->get('group', 'default');
        }

        return $this->group;
    }
}
